package com.xinsoft.controller.wms;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xinsoft.common.Response;
import com.xinsoft.constant.Const;
import com.xinsoft.entity.dto.*;
import com.xinsoft.entity.po.ScmMaterialReturnApply;
import com.xinsoft.entity.po.ScmMaterialReturnApplyItem;
import com.xinsoft.entity.po.SysMaterial;
import com.xinsoft.entity.vo.ScmConsumingApplyItemDetailVo;
import com.xinsoft.entity.vo.ScmMaterialReturnApplyPageVo;
import com.xinsoft.entity.vo.ScmMaterialReturnApplyDetailVo;
import com.xinsoft.entity.vo.ScmMaterialReturnApplyVo;
import com.xinsoft.service.ScmMaterialReturnApplyItemService;
import com.xinsoft.service.ScmMaterialReturnApplyService;
import com.xinsoft.service.SysMaterialService;
import com.xinsoft.service.impl.SyncPushBillAdapter;
import com.xinsoft.utils.ExcelUtils;
import com.xinsoft.validator.ValidatorUtils;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 退料申请
 *
 * @folder 华德/云供应链/仓库管理/退料申请
 */
@RestController
@RequestMapping("/scm/materialReturnApply")
public class ScmMaterialReturnApplyController {

    @Resource(name = "syncPushBillAdapter")
    private SyncPushBillAdapter syncPushBillAdapter;
    @Autowired
    private ScmMaterialReturnApplyService materialReturnApplyService;
    @Autowired
    private ScmMaterialReturnApplyItemService materialReturnApplyItemService;
    @Autowired
    private SysMaterialService materialService;

    /**
     * 分页
     */
    @PostMapping("/pageList")
    public Response<?> pageList(@RequestBody ScmMaterialReturnApplyParam param) {
        return Response.succeed(materialReturnApplyService.findPageListByParam(param));
    }

    /**
     * 退料申请列表
     *
     * @param param
     * @return {@link Response}<{@link IPage}<{@link ScmMaterialReturnApplyVo}>>
     * @response org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.xinsoft.entity.vo.ScmMaterialReturnApplyVo>>
     */
    @PostMapping("/headList")
    public Response<IPage<ScmMaterialReturnApplyVo>> headList(@RequestBody ScmMaterialReturnApplyParam param) {
        return Response.succeed(materialReturnApplyService.headList(param));
    }

    @PostMapping("/pageList1")
    public ScmMaterialReturnApplyPageVo pageList1(@RequestBody ScmMaterialReturnApplyParam param) {
        return null;
    }

    /**
     * 暂存
     */
    @PostMapping("/addOrUpdate")
    @Transactional(rollbackFor = Exception.class)
    public Response<?> addOrUpdate(@RequestBody ScmMaterialReturnApplyDTO dto) {
        // 参数校验
        ValidatorUtils.validateEntity(dto);
        materialReturnApplyService.tempSave(dto);
        return Response.succeed();
    }

    /**
     * 获取详情
     */
    @GetMapping("/detail")
    public Response<ScmMaterialReturnApplyDetailVo> detail(@RequestParam(value = "id", defaultValue = "") Integer id) {
        return Response.succeed(materialReturnApplyService.detail(id));
    }

    /**
     * 删除
     */
    @PostMapping("/del")
    @Transactional(rollbackFor = Exception.class)
    public Response<?> del(@RequestBody List<Integer> ids) {
        ids = ids.stream().distinct().collect(Collectors.toList());
        materialReturnApplyService.del(ids);
        return Response.succeed();
    }

    /**
     * 导出
     */
    @PostMapping("/export")
    public Response<?> export(@RequestBody @ApiParam("查询参数") ScmMaterialReturnApplyParam param, HttpServletResponse response) throws Exception {
        List<ScmMaterialReturnApplyPageVo> list = materialReturnApplyService.findListByParam(param);
        ExcelUtils.exportByEasypoi(list, ScmMaterialReturnApplyPageVo.class, "退料申请", "退料申请", response, "退料申请");
        return Response.succeed();
    }

    /**
     * 审核
     */
    @PostMapping("/audit")
    @Transactional(rollbackFor = Exception.class)
    public Response<?> audit(@RequestBody List<Integer> ids) {
        materialReturnApplyService.audit(ids);
        return Response.succeed();
    }

    /**
     * 反审核
     */
    @PostMapping("/reverseAudit")
    @Transactional(rollbackFor = Exception.class)
    public Response<?> reverseAudit(@RequestBody List<Integer> ids) {
        materialReturnApplyService.reverseAudit(ids);
        return Response.succeed();
    }

    /**
     * 保存并审核
     */
    @PostMapping("/saveAudit")
    @Transactional(rollbackFor = Exception.class)
    public Response<?> saveAudit(@RequestBody ScmMaterialReturnApplyDTO dto) {
        ValidatorUtils.validateEntity(dto);
        Integer id = materialReturnApplyService.tempSave(dto);
        materialReturnApplyService.audit(Collections.singletonList(id));
        return Response.succeed();
    }

    /**
     * 提交（退料入库）
     *
     * @param dto
     * @return {@link Response}<{@link ?}>
     */
    @PostMapping("/submit")
    @Transactional(rollbackFor = Exception.class)
    public Response<?> submit(@Validated @RequestBody MaterialReturnInstockDTO dto) {
        ValidatorUtils.validateEntity(dto);
        List<ScmMaterialReturnApplyItem> list = materialReturnApplyItemService.list(Wrappers.lambdaQuery(ScmMaterialReturnApplyItem.class)
                .eq(ScmMaterialReturnApplyItem::getReturnApplyId, dto.getReturnApplyId()));
        List<Integer> materialIds = list.stream().map(ScmMaterialReturnApplyItem::getMaterialId).collect(Collectors.toList());
        List<SysMaterial> sysMaterials = materialService.listByIds(materialIds);
        Map<Integer, SysMaterial> materialMap = sysMaterials.stream().collect(Collectors.toMap(SysMaterial::getId, o -> o));
        List<String> noExistMaterialList = new ArrayList<>();
        dto.getErpInStockList().forEach(item -> {
            if (!materialIds.contains(item.getMaterialId())) {
                noExistMaterialList.add(materialMap.get(item.getMaterialId()).getMaterialName());
            }
        });
        if (CollUtil.isNotEmpty(noExistMaterialList)) {
            return Response.fail(String.format("物料%s不属于当前单据，请移除", StringUtils.join(noExistMaterialList, "、")));
        }
        // 推送金蝶
        List<ErpInOrOutStockParam> params = BeanUtil.copyToList(dto.getErpInStockList(), ErpInOrOutStockParam.class);
        if (Objects.equals(dto.getReturnApplyTypeId(), Const.DOCUMENT_ID.PRODUCE_RETURN_DOCUMENT)) {
            syncPushBillAdapter.feedingInStock(params);
        }
        if (Objects.equals(dto.getReturnApplyTypeId(), Const.DOCUMENT_ID.OUTSOURCING_RETURN_DOCUMENT)) {
            syncPushBillAdapter.sourcingReturnInStock(params);
        }

        // 更新退料申请已出数量
        dto.getErpInStockList().forEach(item -> {
            materialReturnApplyItemService.update(Wrappers.lambdaUpdate(ScmMaterialReturnApplyItem.class)
                    .setSql("return_num = return_num + " + item.getQty())
                    .eq(ScmMaterialReturnApplyItem::getReturnApplyId, dto.getReturnApplyId())
                    .eq(ScmMaterialReturnApplyItem::getMaterialId, item.getMaterialId()));
        });

        return Response.succeed();
    }
}
